<?php 

$start_time = microtime(true);

ob_start();
ini_set("magic_quotes_runtime", 0);
$DS = DIRECTORY_SEPARATOR;
date_default_timezone_set('Asia/Shanghai');
$timestamp = $_SERVER['REQUEST_TIME'];$_inc_ = true;isset($debug) or $debug = false;$is_gzip = true;
$queries = 0;if($debug) {
	is_callable('display_errors') && ini_set('display_errors', 1);
	error_reporting(E_ALL);
} else {
	ini_set('display_errors', 0);
	error_reporting(0);
}

$app_root = dirname(dirname(__FILE__)).$DS;
$app_base	= $app_root . 'base/';
$app_cfg	= $app_root . 'cfg/';
$app_inc	= $app_root . 'inc/';
$app_lang	= $app_root . 'lang/';
$app_model	= $app_root . 'model/';
$app_view	= $app_root . 'view/';
$app_plugin	= $app_root . 'plugin/';
$app_sdk	= $app_root . 'sdk/';
$app_utils	= $app_root . 'utils/';
$app_data	= $app_root . 'data/';

$PS = PATH_SEPARATOR;
set_include_path(
	get_include_path() . $PS
	. $app_base   . $PS
	. $app_model  . $PS
	. $app_utils  . $PS
	. $app_plugin . $PS
);

if (isset($app_sign)) {
	set_include_path(get_include_path() . $PS . $app_model . $app_sign . '/');
	$app_log	= $app_data . $app_sign . '/log/';
}

if (!isset($web_root)) {
	$web_root = dirname($app_root) . '/webroot';
}
$web_html	= $web_root.'html/';
$web_res	= $web_root . 'resource/';
$app_upload = $web_res . 'uploadfiles/';
$web_attach = $web_res . 'attachment/';

$db_driver = 'Mysql';
$db_host = 'localhost';
$db_port = 3306;
$db_charset = 'utf8';
$db_name = 'qixbo_com';
$db_user = 'root';
$db_pass = '985631';
$tbl_pre = 'qxb_';


$app_name = '';
$app_subtitle = 'subtitle';
$server_domain = 'www.qixbo.com';
$cfg_theme = 'qixbo';
$lang = 'zh-cn';
$date_default_timezone = 'asia/shanghai';
$charset = 'utf-8';
$version = '0.1.0';
$icp_code = '';
$copyright = 2011;
$admin_email = 'qixbo.com@gmail.com';
$site_keyword = '名牌导购';
$site_description = '';


$path_max_file_num = 10;
$mail_word_wrap = 80;
$mail_is_html = 1;
$send_mail_type = 'smtp';
$smtp_ssl = 0;
$smtp_host = 'smtp.gmail.com';
$smtp_port = 465;
$smtp_user = 'qixbo.com@gmail.com';
$smtp_pass = 'qixbo#gmailmima';
$mem_host = 'localhost';
$mem_port = '33133';


$use_session = 1;
$session_time = 86400;
$ck_expire = 86400;
$user_need_active = 0;
$username_max_len = 16;
$username_min_len = 3;
$first_login_coin = 1000;
$first_login_point = 0;
$first_login_credit = 0;
$first_login_honor = 0;
$powered_by = 'QIXBO.COM';
$default_comment_status = 0;

$mb_plugin = array(
	'music',
	'video',
);

mb_internal_encoding($charset);

if (isset($_COOKIE['lang']) && is_dir($app_lang.$_COOKIE['lang'].'/')) {
	$lang = $_COOKIE['lang'];
}

$suffix_tpl = '.html.php';
function __autoload($className)
{
	if(class_exists($className, false)) {
		return true;
	}
	try {
		require $className.'.class.php';
		L(strtolower($className));
	} catch (Exception $e) {
		throw new Exception(
			sprintf($GLOBALS['LClassFileIsNotExists'], $cls_name),
			E_USER_ERROR
		);
	}
	return true;
}
function C()
{
	$Cs = func_get_args();
	$c = array();
	foreach ($Cs as $cfgName)
	{
		$cfgFile = $GLOBALS['app_cfg'].$cfgName.'.cfg.php';
		if (is_file($cfgFile))
		{
			$tmp = include $cfgFile;
			if (!is_array($tmp))
			{
				continue;
			}
			$c = $c+$tmp;
		}
	}
	return $c;
}
function L()
{
	global $app_lang, $lang;
	$Ls = func_get_args();
	$ret = false;
	foreach ($Ls as $lang_name)
	{
		$lang_file = $app_lang.$lang.'/'.$lang_name.'.lang.php';
		if (is_file($lang_file))
		{
			$tmp = include_once $lang_file;
			if (!is_array($tmp))
			{
				continue;
			}
			$ret = true;
			$GLOBALS = $GLOBALS+$tmp;
		}
		if (isset($app_sign)) {
			$lang_file = $app_lang.$app_sign.$lang.'/'.'/'.$lang_name.'.lang.php';
		}
		if (is_file($lang_file)) {
			$tmp = include_once $lang_file;
			if (!is_array($tmp))
			{
				continue;
			}
			$ret = true;
			$GLOBALS = $GLOBALS+$tmp;
		}
	}
	return $GLOBALS;
}
function iurlencode($key)
{
	if(preg_match('/^apache/i', $_SERVER['SERVER_SOFTWARE']))
	{
		return rawurlencode(str_replace(array('/', '?', '&', '#'), array( Core_Config::get('seo', 'basic', 0) ? '%252F' : '%2F', '%3F', '%26', '%23'), $key));
	} else {
		return rawurlencode(str_replace(array('/', '?', '&', '#'), array('%2F', '%3F', '%26', '%23'), $key));
	}
}
function iurldecode($key)
{
	$key = rawurldecode($key);
	if(preg_match('/^apache/i', $_SERVER['SERVER_SOFTWARE']))
	{
		return str_replace(array('%2F') , array('/') , $key);
	} else {
		return str_replace(array('%2F', '%3F', '%26', '%23'), array('/', '?', '&', '#'), $key);
	}
}
function mkdirext($path, $mode=0775)
{
	if (is_dir($path))
	{
		return true;
	}
	mkdir($path, $mode, true);
	return $path;
}

# 读取不含后缀名的文件名
function getfilename($string='')
{
	$pattern = '/([\w]+)([\.a-zA-Z0-9])/';
	preg_match($pattern,$string,$matches);
	return $matches[1];
}
function fileext($filename, $incdot=0)
{
	if ($incdot)
	{
		return strrchr($filename, '.');
	} else {
		return substr(strrchr($filename, '.'), 1);
	}
}
function writefile($file,$writetext,$filemod='text',$openmod='w',$exit=1)
{
	mkdirext(dirname($file));
	if(!@$fp = fopen($file, $openmod))
	{
		if($exit)
		{
			exit('File :<br>'.path_format($file).'<br>Have no access to write!');
		} else {
			return false;
		}
	} else {
		$text = '';
		if($filemod == 'php')
		{
			$text = "<?php\r\n";
		}
		$text .= $writetext;
		if ($filemod == 'php' && substr($text, -1) != ';') {
			$text .= ';';
		}
		flock($fp, 2);
		fwrite($fp, $text);
		fclose($fp);
		return true;
	}
}
function exceptionHandler($e)
{
	$str  = '<pre>';
	$str .= $e->getMessage()."\n";
	$str .= "File: ".$e->getFile();
	$str .= "\n";
	$str .= "Line: ".$e->getLine();
	$str .= "\n";
	$str .= $e->getTraceAsString();
	$str .= "\n".str_repeat('+', 50)."\n";
	$str .= "\n";
	$die = 0;
	$errno = $e->getCode();
	switch ($errno) {
		case E_ERROR:
		case E_USER_ERROR: $err_type = 'PHP Error';
			$die = 1;
			break;
		case E_WARNING:
		case E_USER_WARNING :
			$err_type = 'PHP Warning';
			break;
		case E_PARSE:
			$err_type = 'Parse Error';
			$die = 1;
			break;
		case E_NOTICE:
		case E_USER_NOTICE :
			$err_type = 'PHP Notice';
			break;
		default:
			$err_type = 'Unknow Error';
			break;
	}
	$str = $err_type.'[#'.$errno.']: '.$str;
	if ($GLOBALS['debug']) {
		echo $str;
	} else {
		$file = 'Exception/'.date('Y,m,d').'.log';
		if (is_file($file) && filesize($file)) {
			}
		App::log($file, $str);
		header('content-type:text/plain;charset=utf-8');
		echo $GLOBALS['LErrorOccurredInRuntimeCode'];
		echo "\r\n\r\n";
		echo $GLOBALS['LErrorOccurredInRuntime'];
	}
	echo "</pre>";
	if ($die == 1) {
		die();
	}
}
function errorHandler($errno, $error, $errfile, $errline)
{
	$str  = '<pre>';
	$str .= $error."\n";
	$str .= "File: ".$errfile;
	$str .= "\n";
	$str .= "Line: ".$errline;
	$str .= "\n".str_repeat('+', 50)."\n";
	$str .= "\n";
	$die = 0;
	switch ($errno) {
		case E_ERROR:
		case E_USER_ERROR: $err_type = 'Error';
			$die = 1;
			break;
		case E_WARNING:
		case E_USER_WARNING :
			$err_type = 'Warning';
			break;
		case E_CORE_ERROR:
		case E_COMPILE_ERROR:
			$str = 'Fatal Error: '.$str;
			$die = 1;
			break;
		case E_PARSE:
			$err_type = 'Parse Error';
			$die = 1;
			break;
		case E_NOTICE:
		case E_USER_NOTICE :
			$err_type = 'Notice';
			break;
		default:
			$err_type = 'Unknow Error';
			break;
	}
	$str = $err_type.'[#'.$errno.']: '.$str.'</pre>';
	if ($GLOBALS['debug']) {
		echo $str;
	} else {
		$file = 'Error/'.date('Y,m,d').'.log';
		if (is_file($file) && filesize($file)) {
			}
		App::log($file, $str);
	}
	if ($die == 1) {
		die();
	}
	return true;
}

$cur_path = dirname($_SERVER['SCRIPT_FILENAME']).'/';

$theme_dir = dirname($_SERVER['PHP_SELF']);
if ($theme_dir == DIRECTORY_SEPARATOR) {
	$theme_dir = '';
} else {
	$theme_dir = substr($theme_dir, 1).'/';
}
$homepage = '首页';
$about = '关于我们';
$contact = '联系我们';
$partners = '合作伙伴';
$adv_price = '广告报价';
$employ = '诚聘英才';
$disclaimer = '法律声明';
$friendlink = '友情链接';
$model_is_developing = '该模块/功能正在开发中，敬请期待。';
$sex = 'Array';
$color = 'Array';
$color_sign = 'Array';
$color_html_code = 'Array';
$font_size_options = 'Array';
$secondsFormats = 'Array';
$add_new_text = '新增';
$please_select_text = '请选择';
$city_text = '城市';
$zipcode_text = '邮政编码';
$address_text = '联系地址';
$phone1_text = '联系电话';
$phone2_text = '联系电话2';
$phone3_text = '联系电话3';
$email_text = '电子邮箱';
$note_text = '备注';
$unknow_category_text = '未分类';
$save_text = '保存';
$verified_save_text = '审核并保存';
$cancel_text = '取消';
$title_text = '标题';
$category_text = '分类';
$url_text = '网址';
$status_text = '状态';
$type_text = '类型';
$color_text = '颜色';
$bg_color_text = '背景颜色';
$font_color_text = '字体颜色';
$font_size_text = '字体大小';
$summary_text = '摘要';
$content_text = '内容';
$keyword_text = '关键字';
$search_text = '查询';
$reg_time_text = '注册时间';
$official_url_text = '官方网址';
$user_login_text = '用户登录';
$username_text = '用户名';
$realname_text = '真实姓名';
$password_text = '密码';
$password2_text = '确认密码';
$gender_text = '性别';
$msn_text = 'MSN';
$mobile_text = '手机';
$login_text = '登录';
$not_logined_text = '从未登录';
$last_login_text = '上次登录';
$coin_text = '虚拟币';
$point_text = '积分';
$credit_text = '声望';
$honor_text = '荣誉';
$LSuccessCode = '1001';
$LSuccess = '操作成功！';
$LFailureCode = '1002';
$LFailure = '操作失败！';
$LErrorOccurredInRuntimeCode = '1003';
$LErrorOccurredInRuntime = '程序运行过程中出现错误！';
$LProcessDataIsEmptyCode = '1004';
$LProcessDataIsEmpty = '需要处理的数据不能为空！';
$LAppIsInstalledCode = '1005';
$LAppIsInstalled = '程序已安装，如果要重新安装请确认并删除安装标志后再重新安装！';
$LEmailIsErrorCode = '1006';
$LEmailIsError = '邮箱格式错误！';
$LMysqlDataExitsCode = '1007';
$LMysqlDataExits = 'Duplicate entry data for condition \'%s\'!';
$LClassFileIsNotExistsCode = '1008';
$LClassFileIsNotExists = '无法加载类文件：[%s]。';
$LTplFileNotExistCode = '1009';
$LTplFileNotExist = '模板文件: \"<strong>%s</strong>\" 不存在或没有访问权限！';
$LDisAllowedMimeTypeCode = '1010';
$LDisAllowedMimeType = '不允许的文件类型！';
$LModuleIsNotExistCode = '1011';
$LModuleIsNotExist = '请求的模块[%s]不存在！';
$LDataBaseInsertSuccessCode = '1101';
$LDataBaseInsertSuccess = '数据库数据插入操作成功！';
$LDataBaseInsertFailureCode = '1102';
$LDataBaseInsertFailure = '数据库数据插入操作失败！';
$LDataBaseUpdateSuccessCode = '1103';
$LDataBaseUpdateSuccess = '数据库数据更新操作成功！';
$LDataBaseUpdateFailureCode = '1104';
$LDataBaseUpdateFailure = '数据库数据更新操作失败！';
$LDataBaseDeleteSuccessCode = '1105';
$LDataBaseDeleteSuccess = '数据库数据删除操作成功！';
$LDataBaseDeleteFailureCode = '1106';
$LDataBaseDeleteFailure = '数据库数据删除操作失败！';
$CDataTypeIsNotInt = '2001';
$MDataTypeIsNotInt = '[%s]不是整型数据！';
$CDataTypeIsNotFloat = '2002';
$MDataTypeIsNotFloat = '[%s]不是浮点型数据！';
$CStringLenError = '2002';
$MStringLenError = '[%s]字符串长度必须介于%d到%d之间！';

class App
{
	private static $init = 0;
	private static $args = array();
	private static $include_js = array();
	private static $include_css = array();
	private static $open_throw = 1;
	private static $ob_auto_output = true;
	private static $view = true;
	private static $origin_db_driver = '';
	public static function run()
	{
		self::initialize();
	}
	public static function initialize()
	{
		return true;
	}
	public static function set($var, $val)
	{
		self::${$var} = $val;
	}
	public static function get($var)
	{
		return self::${$var};
	}
	public static function setOptions($vars=array())
	{
		self::$init = 1;
		if (empty($vars))
		{
			$vars = array(
				'app_theme'   => $GLOBALS['app_theme'],
				'suffix_tpl'  => $GLOBALS['suffix_tpl'],
				'theme'       => $GLOBALS['theme'],
				'theme_dir'   => $GLOBALS['theme_dir'],
				'app_cache_tpl' => $GLOBALS['app_cache_tpl'],
				'app_theme_css' => $GLOBALS['app_theme_css'],
				'app_theme_js' => $GLOBALS['app_theme_js'],
				'url_tpl_css' => $GLOBALS['url_tpl_css'],
				'url_tpl_js' => $GLOBALS['url_tpl_js'],
				'url_js' => $GLOBALS['url_js'],
			);
		} else {
			isset($vars['app_theme']) || $vars['app_theme'] = $GLOBALS['app_theme'];
			isset($vars['suffix_tpl']) || $vars['suffix_tpl'] = $GLOBALS['suffix_tpl'];
			isset($vars['theme']) || $vars['theme'] = $GLOBALS['theme'];
			isset($vars['theme_dir']) || $vars['theme_dir'] = $GLOBALS['theme_dir'];
			isset($vars['app_cache_tpl']) || $vars['app_cache_tpl'] = $GLOBALS['app_cache_tpl'];
			isset($vars['app_theme_css']) || $vars['app_theme_css'] = $GLOBALS['app_theme_css'];
			isset($vars['app_theme_js']) || $vars['app_theme_js'] = $GLOBALS['app_theme_js'];
			isset($vars['url_tpl_css']) || $vars['url_tpl_css'] = $GLOBALS['url_tpl_css'];
			isset($vars['url_tpl_js']) || $vars['url_tpl_js'] = $GLOBALS['url_tpl_js'];
			isset($vars['url_js']) || $vars['url_js'] = $GLOBALS['url_js'];
		}
		isset($vars['script_name']) || $vars['script_name'] = basename($_SERVER['SCRIPT_NAME'], '.php');
		self::$args = $vars;
		Tpl::init($vars);
	}
	public static function view()
	{
		if (!self::$view) {
			return true;
		}
		if (!self::$init) {
			self::setOptions();
		}
		$arg = func_get_args();
		if (empty($arg))
		{
			$arg = array(0, self::$args['script_name']);
		} elseif (!isset ($arg[1])) {
			$arg[1] = self::$args['script_name'];
		}
		if ($arg[0]===1 || $arg[0]===true)
		{
			$autoHf = array('header','footer');
			$tpl = $arg[1];
		} elseif (is_array($arg[0])){
			$autoHf = $arg[0];
			$tpl = $arg[1];
		} else {
			$autoHf = 0;
			$tpl = (is_string($arg[0])) ? $arg[0] : self::$args['script_name'];
			if (is_string($arg[0]))
			{
				$more_tpl = explode(',', $arg[0]);
			} elseif (is_array($arg[0])) {
				$more_tpl = $arg[0];
			} elseif (is_string($arg[1])) {
				$more_tpl = explode(',', $arg[1]);
			} elseif (is_array($arg[1])) {
				$more_tpl = $arg[1];
			}
		}
		extract($GLOBALS);

		if ($autoHf)
		{
			include Tpl::load($autoHf[0]);
			include Tpl::load($tpl);
			include Tpl::load($autoHf[1]);
		} else {
			foreach ($more_tpl as $tpl)
			{
				include Tpl::load($tpl);
			}
		}
		if (self::$ob_auto_output) {
			ob_end_flush();
		}
		return true;
	}
	public static function get_g_msg($class, $success_code=0)
	{
		if (empty($success_code)) $success_code = $GLOBALS['LSuccessCode'];
		$class = ucfirst($class);
		if (method_exists($class, 'get')) {
			$code = call_user_func(array($class, 'get'), 'code');
			$desc = call_user_func(array($class, 'get'), 'msg');
		} else {
			$code = eval('return '.$class.'::$code;');
			$desc = eval('return '.$class.'::$msg;');
		}
		if ($success_code == $code)
		{
			$type = 'Success';
		} else {
			$type = 'Failure';
		}
		$g_msg = array(
			'type' => $type,
			'code' => $code,
			'desc' => $desc,
		);
		return $g_msg;
	}
	public static function switch_db_driver($driver='')
	{
		if (!$driver) {
			if (self::$origin_db_driver == '') {
				self::$origin_db_driver = $GLOBALS['db_driver'];
				$GLOBALS['db_driver'] = 'Mysql';
			} else {
				$GLOBALS['db_driver'] = self::$origin_db_driver;
			}
		} else {
			self::$origin_db_driver = $GLOBALS['db_driver'];
			$GLOBALS['db_driver'] = $drvier;
		}
		return true;
	}
	public static function log ($file, $data=null) {
		$file = $GLOBALS['log_root'].$file;
		mkdir(dirname($file), 0755, true);
		for ($i=0; $i<5; $i++) {
			if (!file_exists($file)) {
				$fp = @fopen($file, 'ab+');
			}
			elseif ( filesize($file) > 10000000000 ) {
				$filepart = explode('.', $file);
				$file = $filepart[0].date(',H_i').$filepart[1];
			}
			if (is_writable($file)) {
				if (empty($fp)) {
					$fp = @fopen($file, 'ab+');
				}
				@flock($fp, LOCK_EX); @fwrite($fp, $data); @flock($fp, LOCK_UN); @fclose($fp);
				break;}
			if ($i == 4) { $filename = basename($file);
				$file = $dirname.'/'.date('Y-m-d.H-i-s').'-_-'.$filename;
				if (@$fp=@fopen($file, 'ab+')) {
					@fwrite($fp, $data); @fclose($fp);
				}
			}
			usleep(300);}
		return true;
	}
}
class Db extends pdo
{
	public static $code = null;
	public static $msg = '';
	private static $connectList = array();
	private static $host = 'localhost';
	private static $name = '';
	private static $user = 'root';
	private static $pass = '';
	private static $charset = 'utf8';
	private static $persistent = false;
	protected static $rows = 0;
	protected $priKey = 'id';
	protected static $errors = null;

	protected static $dbh = null;
	public static $queries = 0;
	public static $stmt = null;
	private static $canEndTransaction = true;
	private static $isStartTransaction = false;public static function connect($cfg=null, $sign='default')
	{
		if (is_array($cfg)) {
			isset($cfg['host']) && self::$host = $cfg['host'];
			isset($cfg['name']) && self::$name = $cfg['name'];
			isset($cfg['user']) && self::$user = $cfg['user'];
			isset($cfg['pass']) && self::$pass = $cfg['pass'];
			isset($cfg['charset']) && self::$charset = $cfg['charset'];
			isset($cfg['persistent']) && self::$persistent = $cfg['persistent'];
		}
		$dns = 'mysql:dbname='.self::$name.';host='.self::$host;
		$options = array(
			PDO::MYSQL_ATTR_INIT_COMMAND => 'set names \''.self::$charset.'\'',
			PDO::ATTR_PERSISTENT => self::$persistent
		);
		self::$dbh = new PDO( $dns, self::$user, self::$pass, $options);
		self::$connectList[$sign] = self::$dbh;
		}
	public static function switchDb($sign)
	{
		if (isset(self::$connectList[$sign])) {
			self::$dbh = self::$connectList[$sign];
			return self::$dbh;
		} else {
			return false;
		}
	}
	public static function setTransactionState($state)
	{
		self::$canEndTransaction = $state;
	}
	public static function startTransaction()
	{
		if (self::$isStartTransaction) {
			return true;
		} else {
			self::$dbh->beginTransaction();
			self::$isStartTransaction = true;
			return true;
		}
	}
	public static function commitTransaction()
	{
		if (self::$isStartTransaction) {
			if (self::$canEndTransaction) {
				self::$dbh->commit();
				self::$isStartTransaction = false;
			}
			return true;
		} else {
			return false;
		}
	}
	public static function rollBackTransaction()
	{
		if (self::$isStartTransaction) {
			if (self::$canEndTransaction) {
				self::$dbh->rollBack();
				self::$isStartTransaction = false;
			}
			return true;
		} else {
			return false;
		}
	}
	public static function execute($sql, $params=null)
	{
		self::$queries++;
		if (empty($sql)) {
			debug_print_backtrace();
			exit;
		}
		if (is_null($params)) {
			self::$rows = self::$dbh->exec($sql);
			if (self::$rows === false) {
				self::$errors = self::$dbh->errorInfo();
				self::$errors['sql'] = $sql;
				self::$errors['params'] = $params;
				return false;
			} else {
				return true;
			}
		} else {
			self::$stmt = self::$dbh->prepare($sql);
			if (is_array($params)) {
				$param_list = array();
				foreach ($params as $k=>$v) {
					$param_list[$k] = $v;
				}
				$params = $param_list;
				$result = self::$stmt->execute($params);
			} else {
				$result = self::$stmt->execute();
			}
			if (false === $result) {
				self::$errors = self::$stmt->errorInfo();
				self::$errors['sql'] = $sql;
				self::$errors['params'] = $params;
				self::$rows = 0;
			} else {
				self::$errors = null;
				self::$rows = self::$stmt->rowCount();
			}
			return $result;
		}
	}
	public static function affect_rows()
	{
		return self::$rows;
	}
	public static function getCounts($table, $where='', $params=null)
	{
		if ($where) {
			$sql = 'select count(*) from '.$table.' where '.$where;
			return (int)self::fetch_one($sql, $params);
		} else {
			$sql = 'select count(*) from '.$table;
			return (int)self::fetch_one($sql, $params);
		}
	}
	public static function fetches($sql, $params=null, $style=null)
	{
		empty($params) && $params=1;
		empty($style) && $style=PDO::FETCH_ASSOC;
		self::execute($sql, $params);
		if (self::$stmt->columnCount() == 1) {
			$style = PDO::FETCH_COLUMN;
		}
		$ret = self::$stmt->fetchAll($style);
		if (!$ret) {
			self::$errors = self::$stmt->errorInfo();
			self::$errors['sql'] = $sql;
			self::$errors['params'] = $params;
		} else {
			self::$errors = null;
		}
		self::$stmt->closeCursor();
		self::$stmt = null;
		return $ret;
	}
	public static function fetch_one($sql, $params=null, $style=null)
	{
		if (false === strpos($sql, ' limit ') && 0 === strpos($sql, 'select')) {
			$sql .= ' limit 1';
		}
		empty($params) && $params=1;
		empty($style) && $style=PDO::FETCH_ASSOC;
		self::execute($sql, $params);
		$ret = self::$stmt->fetch();
		if (!$ret) {
			self::$errors = self::$stmt->errorInfo();
			self::$errors['sql'] = $sql;
			self::$errors['params'] = $params;
		} else {
			self::$errors = null;
		}
		if (self::$stmt->columnCount() == 1 && !empty($ret)){
			$ret = current($ret);
		}
		self::$stmt->closeCursor();
		self::$stmt = null;
		return $ret;
	}
	public static function select($table, $field='*', $where='', $param=null,
			$offset=0, $limit=0, $order='')
	{
		empty($field) && $field = '*';
		empty($where) || $where =" where $where";
		empty($order) || $order =" order by $order";
		$sql = 'select '.$field.' from `'.$table.'`'.$where;
		$sql .= $order;
		if ($limit>0 && $limit>$offset) {
			$sql .= ' limit '.$offset.','.$limit.' ';
		}
		if ($limit == 1) {
			return self::fetch_one($sql, $param);
		} else {
			return self::fetches($sql, $param);
		}
	}
	public static function read($table, $value, $field=null, $fetch_field='*')
	{
		if (is_null($field)) {
			if (!empty(self::$priKey)) {
				$field = self::$priKey;
			} else {
				$field = 'id';
			}
		}
		$key = ':'.$field;
		$sql = 'select '.$fetch_field.' from `'.$table
				.'` where `'.$field.'`='.$key;
		$params = array($key=>$value);
		return self::fetch_one($sql, $params);
	}
	public static function insert($table, $data)
	{
		$params = array();
		$fieldList = array();
		$valueList = array();
		if (is_array(current($data))) {
			$dataNums = count($data);
			$needFieldList = 1;
			$i = 1;
			foreach ($data as $fa) {
				$tmpValues = array();
				foreach ($fa as $field => $value)
				{
					$needFieldList && $fieldList[] = '`'.$field.'`';
					$params_key = ':'.$field.$i;
					$tmpValues[] = $params_key;
					$params[$params_key] = $value;
				}
				$i++;
				$needFieldList = 0;
				$tmpValues = join(', ', $tmpValues);
				$valueList[] = '('.$tmpValues.')';
			}
			$fieldStr = join(', ', $fieldList);
			$valueStr = join(",\n", $valueList);
			$sql = "INSERT INTO `$table` ($fieldStr) VALUES $valueStr";
		} else {
			$dataNums = 1;
			foreach ($data as $field => $value) {
				$fieldList[] = '`'.$field.'`';
				$params_key = ':'.$field;
				$valueList[] = $params_key;
				$params[$params_key] = $value;
			}
			$fieldStr = join(', ', $fieldList);
			$valueStr = join(', ', $valueList);
			$sql = "INSERT INTO `$table` ($fieldStr) VALUES ($valueStr)";
		}
		$ret = self::execute($sql, $params);
		if (!$ret) {
			self::$rows = 0;
			self::$code = $GLOBALS['LDataBaseInsertFailureCode'];
			self::$msg  = $GLOBALS['LDataBaseInsertFailure'];
		} elseif ($dataNums>1) {
			self::$code = $GLOBALS['LDataBaseInsertSuccessCode'];
			self::$msg  = $GLOBALS['LDataBaseInsertSuccess'];
		} else {
			self::$code = $GLOBALS['LDataBaseInsertSuccessCode'];
			self::$msg  = $GLOBALS['LDataBaseInsertSuccess'];
		}
		return $ret;
	}
	public static function last_insert_id($name=null)
	{
		return self::$dbh->lastInsertId($name);
	}
	public static function get_auto_increment($table_name)
	{
		$sql = 'SHOW TABLE STATUS LIKE \''.$table_name.'\'';
		$record = self::fetch_one($sql);
		return $record['Auto_increment'];
	}
	public static function update($table, $data, $where='', $params=null, 
			$order='', $limit=0, $retSql=0)
	{
		$set_list = array();
		is_null($params) && $params=array();
		foreach ($data as $field => $value) {
			if (false !== strpos($value, '`')) {
				$set_list[] = '`'.$field.'`='.$value;
			} else {
				$params_key = ':'.$field;
				$set_list[] = '`'.$field.'`='.$params_key;
				$params[$params_key] = $value;
			}
		}
		$set = implode(',', $set_list);
		if ($where) {
			$where = ' where ' . $where;
		}
		if (!empty($order)) {
			$order = ' order by '.$order;
		} else {
			$order = '';
		}
		if (!empty($limit)) {
			$limit = ' limit '.(int)$limit;
		} else {
			$limit = '';
		}
		$sql = 'update ' . $table . ' set ' . $set . $where . $order . $limit;
		$ret = self::execute($sql, $params);
		if ($ret === false)
		{
			self::$rows = 0;
			self::$code = $GLOBALS['LDataBaseUpdateFailureCode'];
			self::$msg  = $GLOBALS['LDataBaseUpdateFailure'];
		} else {
			self::$code = $GLOBALS['LDataBaseUpdateSuccessCode'];
			self::$msg  = $GLOBALS['LDataBaseUpdateSuccess'];
		}
		return $ret;
	}
	public static function delete($table, $where, $params=null)
	{
		$sql = 'delete from '.$table.' where '.$where;
		$ret = self::execute($sql, $params);
		if ($ret === false) {
			self::$rows = 0;
			self::$code = $GLOBALS['LDataBaseDeleteFailureCode'];
			self::$msg  = $GLOBALS['LDataBaseDeleteFailure'];
		} else {
			self::$code = $GLOBALS['LDataBaseDeleteSuccessCode'];
			self::$msg  = $GLOBALS['LDataBaseDeleteSuccess'];
		}
		return $ret;
	}
	public static function show_tables()
	{
		$sql = 'show tables';
		$arr = self::fetches($sql, null, PDO::FETCH_COLUMN);
		$result = array();
		foreach ($arr as $v) {
			$result[] = $v;
		}
		return $result;
	}
	public static function errors($errors=false)
	{
		if ($errors === false) {
			return self::$errors;
		} else {
			self::$errors = $errors;
			return self::$errors;
		}
	}
}
class Model
{
	protected $tbl_pre	= null;protected $tbl		= 'model';protected $_tbl		= '';protected $priKey	= 'id';
	protected $fields	= array();
	protected $errors	= null;
	public $page_panel	= '';
	public function __construct($tbl='', $tbl_pre='')
	{
		if ($tbl_pre) {
			$this->tbl_pre = $tbl_pre;
		} elseif (is_null($this->tbl_pre)) {
			$this->tbl_pre = $GLOBALS['tbl_pre'];
		}
		if ($tbl) {
			$this->tbl = $tbl;
		}
		$this->_tbl = $this->tbl_pre.$this->tbl;
		$this->fields = C('fields/'.$this->tbl);
		return $this;
	}
	public function add2Table($data)
	{
		if ($this->fields)
		foreach ($this->fields as $field_name => $cfg)
		{
			if (!isset($data[$field_name])) {
				$data[$field_name] = $cfg['df_val'];
			} else{
				$val = $data[$field_name];
				if ($cfg['type']=='int' && !(is_int($val) || ctype_digit($val)) ) {
					$this->errors(
						array(
							'code'	=> $GLOBALS['CDataTypeIsNotInt'],
							'msg'	=> sprintf($GLOBALS['MDataTypeIsNotInt'], $field_name),
						)
					);
					return false;
				} elseif ($cfg['type']=='float' && !is_numeric($val)) {
					$this->errors(
						array(
							'code'	=> $GLOBALS['CDataTypeIsNotFloat'],
							'msg'	=> sprintf($GLOBALS['MDataTypeIsNotFloat'], $field_name),
						)
					);
					return false;
				} elseif ($cfg['type']=='string') {
					$len = mb_strlen($val);
					if ((isset($cfg['min_len']) && $len < $cfg['min_len'])
							 || (isset($cfg['max_len']) && $len > $cfg['max_len']) 
					) {
						$this->errors(
							array(
								'code'	=> $GLOBALS['CStringLenError'],
								'msg'	=> sprintf(
											$GLOBALS['MStringLenError'], 
											$field_name,
											$cfg['min_len'], $cfg['max_len']
								)
							)
						);
						return false;
					}
				}
			}
		}
		$ret = Db::insert($this->_tbl, $data);
		if ($ret) {
			$this->errors(null);
			return true;
		} else {
			$errors = Db::errors();
			$this->errors(
				array(
					'code'	=> $errors[1],
					'info'	=> $errors[2]
				)
			);
			return false;
		}
	}
	public function read($val, $field='')
	{
		if ($field) {
			return Db::read($this->_tbl, $val, $field);
		} else {
			return Db::read($this->_tbl, $val, $this->priKey);
		}
	}
	public function getCounts($where)
	{
		if (is_string($where)) {
			return Db::getCounts($this->_tbl, $where);
		} else {
			return Db::getCounts($this->_tbl, join(' and ', $where));
		}
	}
	public function getList($args=array())
    {
        extract($args);
        !isset($page_size) && $page_size = 20;
    	if (empty($where))
    	{
			$where = '';
		} elseif (is_string($args['where'])) {
			$where = $args['where'];
		}
		$_whr = array();
		(!isset($params) || !is_array($params)) && $params = array();
		if (!empty($cid))
		{
			$_whr[] = 'cid=:cid';
			$params['cid'] = $cid;
		}
		if (isset($status) && $status != 'all') {
			$_whr[] = 'status=:status';
			$params['status'] = $status;
		}

        if (!empty($where))
        {
	        $where = join(' and ', $where);
			$where = ' where '.$where;
        }
        $rows = Db::getCounts($this->_tbl, $where, $params);
        if (!$rows && !is_null(Db::$errors)) {
        	$this->errors(
				array(
					'code'	=> Db::$errors[1],
					'info'	=> Db::$errors[2]
				)
			);
			return false;
        }
		if (!empty($has_pages))
		{
			Page::init($page_size, $rows);
			Page::set_from_to($page_size);
			$page_start = Page::$from;
		} else {
			$has_pages = false;
			$page_start = 0;
		}
		empty($fields) && $fields = '*';
		if (empty($order))
		{
			$order = ' order by '.$this->priKey.' desc';
		} else {
			$order = ' order by '.$order;
		}
		$sql = 'select '.$fields.' from '.$this->_tbl.' '
				.$where.$order." limit $page_start, $page_size";
        $list = Db::fetches($sql, $params);
		if ($has_pages == 1)
		{
			$this->page_panel = Page::generate($_POST);
		}
        return $list;
	}
	public function errors($errors=false)
	{
		if ($errors === false) {
			return $this->errors;
		} else {
			$this->errors = $errors;
			return $this->errors;
		}
	}
}
define('PAGINATE_BY_NAVPAGE', 1);
define('PAGINATE_BY_PAGECODE', 2);
define('PAGINATE_BY_SELECT', 4);
define('PAGINATE_BY_INPUT', 8);
define('PAGINATE_BY_TPL', 16);
define('PAGINATE_BY_COMMON', 32);
class Page {
	public static $page_var = 'page';
	public static $page_panel = 'page_panel';
	public static $page_panel_class = 'page_panel_class';
	public static $page_form_id = 'page_panel_form';
	public static $size;		  public static $page;		  public static $total;		 public static $from;		  public static $to;			public static $rows;		  public static $max_index = 15;
	public static $first;
	public static $qs_tpl;
	public static $form_method = 'GET';
	public static $show_page_num = 8;
	public static function init($size=10, $rows=0)
	{
		if ($size>0) {
			self::$size = $size;
		} elseif($size==0) {
			self::$size = 10;
		}
		if ($rows>0) {
			self::$rows = $rows;unset($rows);
		} else {
			self::$total = 0;
			self::$rows = 0;
		}
		if (self::$rows > 0 ) {
			self::$total = ceil(self::$rows/self::$size);
		}
		self::set_page();
		self::set_from_to(self::$size);
		return true;
	}
	public static function set_from_to($size=0)
	{

		if (empty(self::$page)) {
			self::set_page();
		}
		if (!empty($size)) {
			self::$size = $size;
		}
		self::$from = (self::$page-1) * (self::$size);
		self::$to = self::$from + self::$size;
		if (self::$to > self::$rows) {
			self::$to = self::$rows;
		}
	}
	public static function set_page() {
		if (empty($_REQUEST[self::$page_var])) {
			self::$page = 1;
		} else {
			self::$page = (int)$_REQUEST[self::$page_var];
		}
		if (self::$page < 1) {
			self::$page = 1;
		} elseif (!empty(self::$total) && self::$page > self::$total ) {
			$qs = sprintf(self::$qs_tpl, self::$total);
			$last = $_SERVER['PHP_SELF'].'?'.$qs;
			self::$page = self::$total;
		} else {
			;}
		return true;
	}
	public static function parseQs() {
		parse_str($_SERVER['QUERY_STRING'], $qs_arr);
		if (array_key_exists(self::$page_var, $qs_arr)) {
			unset($qs_arr[self::$page_var]);
		}
		$qs = http_build_query($qs_arr);
		if (!empty($qs))
		{
			$qs .= '&';
			self::$first = $_SERVER['PHP_SELF'].'?'.$qs;
		} else {
			self::$first = $_SERVER['PHP_SELF'];
		}
		self::$qs_tpl = urldecode($qs.self::$page_var.'=%s');
	}
	public static function generate(
			$param=array(), $type=PAGINATE_BY_PAGECODE, $tpl='')
	{
		self::parseQs();if ($type == PAGINATE_BY_COMMON)
		{
			return self::get_common_page();
		}
		$type == -1 && $type=PAGINATE_BY_NAVPAGE^PAGINATE_BY_SELECT;

		if (self::$rows == 0) {
			self::init(-1, -1);
		}
		if ($type == PAGINATE_BY_TPL) {
			return self::getTplPageTurn($tpl); }
		$qs = http_build_query($param);
		if (!empty($param) && !empty($_POST) && strlen($qs)>1000) {
			self::$form_method = $method = 'POST';
		} else {
			$method = 'GET';
			$param = array_merge($_GET, $param);
		}
		$panel_str = '<div id="'.self::$page_panel.'" style="width:99%;"'
				   .' class="'.self::$page_panel_class.'">'."\n"
				   .'<form id="'.self::$page_form_id.'" name="" method="'.$method.'" '
				   .'action="'.self::$first.'">'."\n"; 
		if ( is_array($param) ) {
			$param_str  = ' ';
			foreach ($param as $key => $value) {
				$except_param = array(self::$page_var, 'submit');
				if ($value!='' && !in_array($key, $except_param)) {
					$panel_str .= '<input type="hidden" '
						.'name="'.$key.'" value="'.$value.'">'."\n";
				}
			}
		}
		$panel_str .= '共有记录：'.self::$rows.' 条&nbsp;&nbsp;';
		if (self::$rows>0) {
			if ((self::$from+1) == self::$to) {
				$show = '显示第 '.self::$to.' 条';
			} else {
				$show = '显示：'.(self::$from+1).'-'.self::$to.' 条';
			}
			$panel_str .= $show.'&nbsp;&nbsp;当前页: <font color="#ff0000">'
						.self::$page.'</font>/'.self::$total;
		} else {
			 $panel_str .= '';
		}
		if (self::$rows <= 0){
			$panel_str .= "\n</form>\n</div>\n";
			return $panel_str;
		}
		$panel_str .= '&nbsp;&nbsp;&nbsp;';
		if (self::$rows>0 && ($type&PAGINATE_BY_NAVPAGE)) {
			$panel_str .= self::get_nav_page_turn();
		}
		if (self::$rows>0 && ($type&PAGINATE_BY_SELECT)) {
			$panel_str .= self::get_select_page_turn();
		}
		if (self::$rows>0 && ($type&PAGINATE_BY_INPUT)) {
			$panel_str .= self::get_input_page_turn();
		}
		if (self::$rows>0 && ($type&PAGINATE_BY_PAGECODE)) {
			$panel_str .= self::get_page_code_turn();
		}
		$panel_str .= "\n</form>\n</div>\n";
		if ($type == PAGINATE_BY_COMMON)
		{
			$panel_str = self::get_common_page();
		}
		return $panel_str;
	}
	public static function get_nav_page_turn()
	{
		$space = '&nbsp;&nbsp;&nbsp;';
		$page_first = '';
		$page_pre  = '';
		$page_next  = '';
		$page_last   = '';
		if (self::$page != 1) {
			$page_first = '<a href="'.self::$first.'">【首页】</a>&nbsp;';
		}
		$uri = $_SERVER['PHP_SELF'] . '?';
		if (self::$page > 1){
			$qs = sprintf(self::$qs_tpl, self::$page - 1);
			$page_pre = '<a href="'.$uri.$qs.'">【上一页】</a>&nbsp;';
		}
		if (self::$page < self::$total) {
			$page = self::$page<self::$total ? (self::$page + 1) : self::$total;
			$qs = sprintf(self::$qs_tpl, $page);
			$page_next ='<a href="'.$uri.$qs.'">【下一页】</a>&nbsp;';
		}
		if (self::$page != self::$total) {
			$qs = sprintf(self::$qs_tpl, self::$total);
			$page_last = '<a href="'.$uri.$qs.'">【末页】</a>&nbsp;';
		}
		$ret = $page_first . $page_pre . $page_next . $page_last;
		if (!empty($ret)) {
			$ret = $space.$ret;
		}
		return $ret;
	}
	public static function get_select_page_turn(){
		$ret = '&nbsp;转到第 <select name="'.self::$page_var.'" '
			  .'onChange="this.form.submit()" '
			  .'style="font-size:12px; vertical-align:baseline">'.chr(10);
		for ($j=1;$j<=(self::$total);$j++){
			if ($j == self::$page) {
				$ret .= "<option selected>$j</option>\n";
			}else {
				$ret .= "<option>$j</option>\n";
			}
		}
		$ret .= "</select> 页\n";
		return $ret;
	}
	public static function get_input_page_turn() {
		return '转到第
			<input name="'.self::$page_var.'" type="text" style="align:center;
			height:10pt;width:18pt;
			font-size:9pt;
			text-align: center;
			padding:0px 1px 0px 1px;
			border-bottom:1px solid #000000;
			border-left:0px;
			border-top:0px;
			border-right:0px">&nbsp;页
			<input type="submit" value="GO"
			style="height: 11pt;width:20pt;font-size:9pt;
			padding:2px 0px 0px 0px; margin: 1px;
			border:0px dashed #000000;">';
	}
	public static function get_page_code_turn()
	{
		$tmp = ceil(self::$show_page_num/2);
		if (self::$page>$tmp && self::$total>self::$show_page_num) {
			$start = self::$page-$tmp+1;
			$end = self::$page+$tmp;
			if ($end > self::$total) {
				$start = self::$total-(self::$show_page_num-1);
				$end = self::$total;
			}
		} else {
			$start = 1;
			if (self::$total>self::$show_page_num) $end = self::$show_page_num;
			else $end = self::$total;
		}
		$str = "\n";
		if (self::$page != 1)
		{
			$str .= '<a href="'.self::$first.'" class="page_first_label">'
					.'<span>&lt;</span>&nbsp;第一页</a>&nbsp&nbsp';
			if ($start != 1)
			{
				$str .= '...&nbsp;';
			}
			$str .= "\n";
		}
		for($i=$start;$i<=$end;$i++) {
			$pageurl = $_SERVER['PHP_SELF'].'?'.sprintf(self::$qs_tpl, $i);
			if ($i==self::$page) {
				$str .= '<span class="current">'.$i.'</span>&nbsp';
			} else {
				$str .= '<a href="'.$pageurl.'" class="page_item">'.$i.'</a>&nbsp';
			}
			$str .= "\n";
		}
		$qs = sprintf(self::$qs_tpl, self::$total);
		if (self::$page != self::$total)
		{
			if ($end != self::$total)
			{
				$str .= '...&nbsp;';
			}
			$str .= '<a href="'.$_SERVER['PHP_SELF'].'?'.$qs.'" '
					.'class="page_last_label">'
					.'最后一页&nbsp;<span>&gt;</span></a>&nbsp;&nbsp';
			$str .= "\n";
		}
		return $str;
	}
 }
if (false == defined('START_DELIMITER') && false == defined('END_DELIMITER'))
{
define('START_DELIMITER', '{');
	define('END_DELIMITER', '}');
}

define('HALT_FOR_FILE_NOT_EXIST', 1);

class Tpl
{
	private static $is_inited = false;
	private static $tpl_file = '';
	private static $tpl_cache_file = '';
	private static $tpl_contents = '';
	public static $load_times = 0;
	public static $life_time = 1000;
	public static $vars = array();
	public static $recache = 0;
	public static $is_using_cache = 0;
	public static function init($vars=array())
	{
		self::$vars = array(
			'app_theme'   => $vars['app_theme'],
			'suffix_tpl'  => $vars['suffix_tpl'],
			'theme'       => $vars['theme'],
			'theme_dir'   => $vars['theme_dir'],
			'app_cache_tpl' => $vars['app_cache_tpl'],
		);
	}
	public static function load($tpl_name=null)
	{
		extract(self::$vars);
		self::$load_times++;
		$str = '';
		if (empty($tpl_name))
		{
			$tpl_name = self::$vars['script_name'];
		}
		$tpl_file = self::$vars['app_theme'].self::$vars['theme_dir'].
					$tpl_name.self::$vars['suffix_tpl'];
		if (!is_file($tpl_file))
		{
			self::halt(HALT_FOR_FILE_NOT_EXIST, $tpl_file);
		}
		self::$vars['url_tpl_css'] = self::$vars['app_theme']
					.self::$vars['theme_dir'].'css/';
		$str = '';
		if( !($fp = fopen($tpl_file, 'r')) )
		{
			self::halt(HALT_FOR_FILE_NOT_EXIST);	
		}
		$filesize = filesize($tpl_file);
		empty($filesize) && $filesize = 1;
		$str = fread($fp, $filesize);
		fclose($fp);
		$theme = empty(self::$vars['theme']) ? '' : self::$vars['theme'].'/';
		$cache_file = self::$vars['app_cache_tpl'].$theme.$tpl_name.'.php';
		clearstatcache();
		if (is_file($cache_file)) {
			$cache_time = filemtime($cache_file);
		} else {
			$cache_time = 0;
		}
		$recache = self::$recache || !empty($_REQUEST['recache_all']) 
					|| filemtime($tpl_file) > $cache_time;
		$expire = self::$life_time >= 0 && (time() - $cache_time) > self::$life_time;
		if($GLOBALS['debug'] || !is_file($cache_file) || $expire || $recache)
		{
			App::docss();
			App::dojs();
			self::parse($str, $cache_file);
		} else {
			self::$is_using_cache = 1;
		}
		return $cache_file;
	}
	public static function make_cache($cache_file, $str)
	{
		$str = trim($str);
		writefile($cache_file, $str, 'text', 'w', 0);
		return true;
	}
	public static function parse($str, $cache_file)
	{
		$str = str_replace('{', START_DELIMITER, $str);
		$str = str_replace('}', END_DELIMITER, $str);
		$sd = preg_quote(START_DELIMITER, '-');
		$ed = preg_quote(END_DELIMITER, '-');
		$sdif = START_DELIMITER;
		$edif = END_DELIMITER;
		extract($GLOBALS);
		$str = str_replace(
			array('<?php exit;?>', '{exit}'), 
			"<?php if (empty(\$GLOBALS['_inc_'])) exit;?>", 
			$str
		);
		if (false!==strpos($str, $sdif.'template'))
		{
			$reg = "~{$sd}template[\s]+([\w\-\_\./]+){$ed}~is";
			preg_match_all($reg, $str, $tpls);
			$tpls = $tpls[1]; $str = preg_replace_callback($reg, 'Tpl::replace_template', $str);
		}
		if (false!==strpos($str, $sdif.'include'))
		{
			$reg = "~{$sd}include[\s]+([\S]+){$ed}~is";
			$replace = "<?php include_once \\1;?>";
			$str = preg_replace($reg, $replace, $str);
		}
		if (false!==strpos($str, $sdif.'php'))
		{
			$reg = '~'.$sd."php[\s]+(.+?)".$ed.'~is';
			$replace = "<?php \\1;?>";
			$str = preg_replace($reg, $replace, $str);
		}
		if (false!==strpos($str, $sdif.'output '))
		{
			$reg = '~'.$sd."output[\s]+(.+?)".$ed.'~e';
			$replace = "eval('return \\1;')";
			$str = preg_replace($reg, $replace, $str);
		}
		if (false!==strpos($str, $sdif.'global'))
		{
			$reg = '~'.$sd."global[\s]+(.+?)".$ed.'~is';
			$replace = "<?php global \\1;?>";
			$str = preg_replace($reg, $replace, $str);
		}
		if (false!==strpos($str, $sdif.'echo') 
				|| false!==strpos($str, $sdif.'?'))
		{
			$reg = '~'.$sd."(?:\?|echo[\s]+)(.+?)".$ed.'~is';
			$replace = "<?php echo \\1;?>";
			$str = preg_replace($reg, $replace, $str);
		}
		if (false!==strpos($str, '{html'))
		{
			$reg = "~<\!\-\-\{html[\s]+(.+?)\}\-\->~is";
			$replace = "\\1";
			$str = preg_replace($reg, $replace, $str);
		}
		if (false!==strpos($str, $sdif.'html'))
		{
			$reg = "~{$sd}html[\s]+(.+?){$ed}~is";
			$replace = "\\1";
			$str = preg_replace($reg, $replace, $str);
		}
		$str = ltrim($str);
		$str = preg_replace("/([\r\n]+)[\t| ]+$/s", "\\1", $str);
		$reg = "~{$sd}(\\\$[a-z_][\w_]*"  ."(?:\[[\S]+?\])*"  ."){$ed}~is";
		$str = preg_replace($reg, "<?php if (isset(\\1)) echo \\1;?>", $str);
		if (false!==strpos($str, $sdif.'isset '))
		{
			$reg = "~{$sd}(?:isset)[\s]+?([\S\s]+?){$ed}~is";
			$replace = "<?php if (isset(\\1)) echo \\1; ?>";
			$str = preg_replace($reg, $replace, $str);
		}
		if (false!==strpos($str, $sdif.'replace '))
		{
			$reg = "~{$sd}replace[\s]+(\\\$[a-z_][\w_]*"  ."(?:\[[\S]+?\])*"  ."){$ed}~ie";
			$replace = 'eval(\'return \\1;\')';
			$str = preg_replace($reg, $replace, $str);
		}
		if (false!==strpos($str, $sdif.'if '))
		{
			$reg = "~{$sd}if[\s]+(.+?)[\s]+do:(.+?)[\s]*{$ed}~is";
			$replace = "<?php if (\\1) {\\2;\n} ?>";
			$str = preg_replace($reg, $replace, $str);
		}
		if (false!==strpos($str, $sdif.'if '))
		{
			$reg = "~{$sd}(if)[\s]+(.+?)[\s]*{$ed}~is";
			$replace = "<?php \\1 (\\2) { ?>";
			$str = preg_replace($reg, $replace, $str);
		}
		if (false!==strpos($str, $sdif.'elseif '))
		{
			$reg = "~{$sd}(elseif)[\s]+(.+?){$ed}~is";
			$replace = "<?php } \\1 (\\2) { ?>";
			$str = preg_replace($reg, $replace, $str);
		}
		if (false!==strpos($str, $sdif.'else'))
		{
			$reg = "~{$sd}(else)[\s]*{$ed}~is";
			$replace = "<?php } \\1 { ?>";
			$str = preg_replace($reg, $replace, $str);
		}
		if (false!==strpos($str, $sdif.'for '))
		{
			$str = preg_replace(
					"~{$sd}for\s+(\S+)\;\s*(\S+){$ed}~",
					"<?php for(\$i=\\1; \$i<=\\2; \$i++) { ?>",
					$str
				);
		}
		if (false!==strpos($str, $sdif.'loop '))
		{
			$str = preg_replace(
					"~{$sd}loop\s+(\S+)\s+(\S+){$ed}~",
					"<?php if(is_array(\\1)) foreach(\\1 as \\2) { ?>",
					$str
				);
			$str = preg_replace(
					"/{$sd}loop\s+(\S+)\s+(\S+)\s+(\S+){$ed}/",
					"\n<?php if(is_array(\\1)) foreach(\\1 as \\2 => \\3) { ?>",
					$str
				);
		}
		if (false!==strpos($str, $sdif.'/if'.$edif))
		{
			$reg = "~{$sd}\/if{$ed}~";
			$replace = "<?php } ?>";
			$str = preg_replace($reg, $replace, $str);
		}
		if (false!==strpos($str, $sdif.'/for'.$edif))
		{
			$reg = "~{$sd}\/for{$ed}~";
			$replace = "<?php } ?>";
			$str = preg_replace($reg, $replace, $str);
		}
		if (false!==strpos($str, $sdif.'/loop'.$edif))
		{
			$reg = "~{$sd}\/loop{$ed}~";
			$replace = "<?php } ?>";
			$str = preg_replace($reg, $replace, $str);
		}
		$reg = "~<\!\-\-([A-Z_][A-Z0-9_\.]*)\-\->~";
		$replace = '<?php echo \\1;?>';
		$str = preg_replace($reg, $replace, $str);
		$reg = "~$sd([A-Z_][A-Z0-9_\.]*)$ed~";
		$replace = '<?php if (defined(\'\\1\')) echo \\1;?>';
		$str = preg_replace($reg, $replace, $str);
		$reg = "~<\!\-\-([\/| )([\*]?)(.+?)(\\2?)(\\1?)\-\->~i";
		$replace = "";
		$str = preg_replace($reg, $replace, $str);

		self::make_cache($cache_file, $str);
		return $str;
	}
	private static function halt($reason=HALT_FOR_FILE_NOT_EXIST, $tpl_file='')
	{
		switch ($reason) {
		case HALT_FOR_FILE_NOT_EXIST:
			$msg = sprintf($GLOBALS['LTplFileNotExist'], $tpl_file);
			throw new Exception($msg, E_USER_ERROR);
			break;
		default:
				;
			break;
		}
	}
	public static function set_var($var)
	{
		if (is_string($var))
		{
			self::$vars[$var] = $GLOBALS[$var];
		} elseif (is_array($var)) {
			foreach ($var as $v)
			{
				self::$vars[$v] = $GLOBALS[$v];
			}
		}
	}
	public static function replace_template($matches)
	{
		$file = $matches[1];
		self::Load($file);
		$theme = empty(self::$vars['theme']) ? '' : self::$vars['theme'].'/';
		$filename = self::$vars['app_cache_tpl'].$theme.$file.'.php';
		$ret = '<?php require_once \''.$filename.'\';?>';
		return $ret;
	}
}
set_exception_handler('exceptionHandler');
set_error_handler("errorHandler");
Db::connect(
	array(
		'host'		=> $db_host, 
		'name'		=> $db_name,
		'user'		=> $db_user,
		'pass'		=> $db_pass,
		'charset'	=> $db_charset
	)
);

